package com.okilo.online.app.request

import android.os.Handler
import android.os.Looper
import android.view.View
import androidx.lifecycle.Lifecycle
import com.okilo.online.app.R
import com.okilo.online.app.common.OkiloComAct
import com.okilo.online.app.dialog.OkiloTipsDlog
import com.okilo.online.app.tools.log.OkiloLog
import org.json.JSONObject
import java.lang.ref.WeakReference
import java.util.Stack

/**
 * 网络请求管理类
 * 统一处理网络异常弹窗和重试逻辑
 */
object NetworkManager {
    private var isShowingDialog = false

    // 存储待重试的请求队列（按照添加顺序）
    private val retryQueue = LinkedHashMap<String, RetryRequest>()

    // 当前显示的对话框
    private var errorDialog: OkiloTipsDlog? = null

    // 注册的 Activity 引用（弱引用避免内存泄漏）
    private val activityStack = Stack<WeakReference<OkiloComAct>>()

    // 添加重试监控
    private var pendingRetryCount = 0//待重试接口数量
    private var completedRetryCount = 0//已完成重试数量

    //提示次数
    private var showCount = 0

    // 当前可用的 Activity（从注册的 Activity 中获取）
    private val availableActivity: OkiloComAct?
        get() = getLatestResumedActivity()

    // 重试请求数据类
    data class RetryRequest(
        val requestId: String = generateRequestId(),
        val requestType: String, // "POST", "UPLOAD" 等
        val url: String,
        val params: Any?, // 可以是 JSONObject, String(文件路径) 等
        val originalCallback: IHttpCallback,
        val timestamp: Long = System.currentTimeMillis(),
        var retryCount: Int = 0
    ) {
        companion object {
            fun generateRequestId(): String {
                return "req_${System.currentTimeMillis()}_${(0..1000).random()}"
            }
        }
    }

    /**
     * 注册 Activity（在 Activity onCreate 中调用）
     */
    fun registerActivity(activity: OkiloComAct) {
        showCount = 0
        synchronized(activityStack) {
            // 清理已销毁的 Activity 引用
            activityStack.removeAll { it.get() == null || it.get()?.isDestroyed == true }
            // 移除已存在的相同Activity引用（避免重复）
            activityStack.removeAll { it.get() == activity }
            // 压入栈顶
            activityStack.push(WeakReference(activity))
        }
        OkiloLog.d("NetworkErrorManager: register activity - ${activity.javaClass.simpleName}")
    }

    /**
     * 取消注册 Activity（在 Activity onDestroy 中调用）
     */
    fun unregisterActivity(activity: OkiloComAct) {
        synchronized(activityStack) {
            activityStack.removeAll { it.get() == activity || it.get() == null }
        }
        OkiloLog.d("NetworkErrorManager: unregister activity - ${activity::class.java.simpleName}")

        // 如果当前显示的对话框属于正在销毁的 Activity，关闭对话框
        if (getLatestResumedActivity() == null && isShowingDialog) {
            resetState()
        }
    }

    /**
     * Activity resumed时调用（在onResume中调用）
     */
    fun onActivityResumed(activity: OkiloComAct) {
        synchronized(activityStack) {
            // 将该Activity移到栈顶
            activityStack.removeAll { it.get() == activity }
            activityStack.push(WeakReference(activity))
        }
        OkiloLog.d("NetworkErrorManager: Activity resumed - ${activity::class.java.simpleName}")
    }

    /**
     * 获取最新的 resumed Activity（用于显示 Dialog）
     */
    private fun getLatestResumedActivity(): OkiloComAct? {
        synchronized(activityStack) {
            // 清理已销毁的 Activity 引用
            activityStack.removeAll { it.get() == null || it.get()?.isDestroyed == true }

            // 从栈顶开始查找第一个resumed的Activity
            return activityStack
                .mapNotNull { it.get() }
                .firstOrNull { !it.isFinishing && !it.isDestroyed && isActivityResumed(it) }
        }
    }

    /**
     * 处理网络错误，决定是否显示全局Dialog
     */
    fun handleNetworkError(errorCode: Int, errorMsg: String, requestData: RetryRequest? = null) {
        // 检查是否应该显示错误提示
        if (!shouldShowErrorDialog(errorCode)) {
            return
        }

        // 如果有请求数据，添加到重试队列
        requestData?.let { request ->
            addToRetryQueue(request)
        }

        // 防止频繁弹窗
        if (isShowingDialog) {
            return
        }

        // 延迟检查Activity状态，给Activity时间进入resumed状态
        Handler(Looper.getMainLooper()).postDelayed({
            showErrorDialogWithRetry(errorCode, errorMsg)
        }, 300) // 延迟300ms，确保Activity已经resumed
    }

    /**
     * 延迟后显示错误对话框
     */
    private fun showErrorDialogWithRetry(errorCode: Int, errorMsg: String) {
        // 再次检查是否正在显示弹窗
        if (isShowingDialog) {
            return
        }

        val activity = availableActivity
        OkiloLog.i("<<<<<<<<<<activity>>>>>>>>${activity?.javaClass?.simpleName}")
        if (activity != null && isActivityResumed(activity)) {
            showGlobalErrorDialog(activity, errorCode, errorMsg)
        } else {
            OkiloLog.w("NetworkErrorManager: No activity available or activity not in recovered state, unable to display network error pop-up window")
        }
    }

    /**
     * 检查Activity是否处于resumed状态
     */
    private fun isActivityResumed(activity: OkiloComAct): Boolean {
        return activity.lifecycle.currentState.isAtLeast(Lifecycle.State.RESUMED)
    }

    /**
     * 添加请求到重试队列
     */
    private fun addToRetryQueue(request: RetryRequest) {
        synchronized(retryQueue) {
            // 检查是否已存在相同的请求（基于URL和参数）
            val existingKey = findExistingRequestKey(request)
            if (existingKey != null) {
                // 更新已有的请求
                retryQueue[existingKey] = request
                OkiloLog.d("NetworkErrorManager: Update requests in the retry queue - ${request.url}")
            } else {
                // 添加新请求
                retryQueue[request.requestId] = request
                OkiloLog.d("NetworkErrorManager: Add to retry queue - ${request.url}")
            }
        }
        OkiloLog.d("NetworkErrorManager: Current retry queue size - ${retryQueue.size}")
    }

    /**
     * 查找已存在的请求Key（防止重复添加）
     */
    private fun findExistingRequestKey(newRequest: RetryRequest): String? {
        return retryQueue.entries.firstOrNull { entry ->
            val existing = entry.value
            existing.url == newRequest.url &&
                    existing.requestType == newRequest.requestType &&
                    areParamsEqual(existing.params, newRequest.params)
        }?.key
    }

    /**
     * 比较参数是否相等
     */
    private fun areParamsEqual(params1: Any?, params2: Any?): Boolean {
        if (params1 == null && params2 == null) return true
        if (params1 == null || params2 == null) return false
        return params1.toString() == params2.toString()
    }

    /**
     * 判断是否应该显示全局错误对话框
     */
    fun shouldShowErrorDialog(errorCode: Int): Boolean {
        return HttpErrorCode.isNetworkError(errorCode)
    }

    /**
     * 显示全局错误对话框
     */
    private fun showGlobalErrorDialog(activity: OkiloComAct, errorCode: Int, errorMsg: String) {
        // 确保在主线程显示对话框
        if (Looper.myLooper() != Looper.getMainLooper()) {
            Handler(Looper.getMainLooper()).post {
                showGlobalErrorDialog(activity, errorCode, errorMsg)
            }
            return
        }

        // 再次检查Activity状态
        if (activity.isFinishing || activity.isDestroyed || !isActivityResumed(activity)) {
            OkiloLog.w("NetworkErrorManager: Activity Status unavailable, cancel the pop-up window display")
            return
        }

        isShowingDialog = true
        try {
            createErrorDialog(activity, errorMsg)
            OkiloLog.d("NetworkErrorManager: Display network error pop-up window")
        } catch (e: Exception) {
            OkiloLog.e("NetworkErrorManager: Failed to display network error pop-up window: ${e.message}")
            isShowingDialog = false
            errorDialog = null
        }
    }

    /**
     * 创建错误对话框
     */
    private fun createErrorDialog(activity: OkiloComAct, errorMsg: String) {
        OkiloLog.e("errorMsg>>>>>>>>$errorMsg")
        var showText = activity.getString(R.string.okilo_dlog_network_error)
        if (showCount >= 3){
            showText = activity.getString(R.string.okilo_dlog_network_check)
        }
        showCount += 1

        errorDialog = OkiloTipsDlog(activity,activity.javaClass.simpleName,object : OkiloTipsDlog.IOkiloTipsClickCallback{
            override fun onClick(view: View?) {
                activity.showOkiloLoading()
                Handler(Looper.getMainLooper()).postDelayed({
                    executeRetryQueue()
                }, 500) // 延迟500ms执行重试
            }
        })
        errorDialog?.setOnDismissListener {
            isShowingDialog = false
            errorDialog = null
        }
        errorDialog?.setCancelable(false)
        errorDialog?.setCanceledOnTouchOutside(false)
        errorDialog?.show()
        errorDialog?.sOkiloDlogTipsButtonConfirmText(activity.getString(R.string.okilo_btn_reload))
        errorDialog?.iOkiloDlogTipsDoubleButton(false)
        errorDialog?.sOkiloDlogTipsMsgText(showText)
    }

    /**
     * 执行重试队列（按照添加顺序）
     */
    private fun executeRetryQueue() {
        if (retryQueue.isEmpty()) {
            OkiloLog.d("NetworkErrorManager: The retry queue is empty")
            return
        }

        // 复制队列并清空原队列（防止重试过程中新请求加入造成混乱）
        val queueToRetry = synchronized(retryQueue) {
            LinkedHashMap(retryQueue).also {
                retryQueue.clear()
            }
        }
        // 初始化计数器
        pendingRetryCount = queueToRetry.size
        completedRetryCount = 0

        OkiloLog.d("NetworkErrorManager: Start retry execution, with a total of ${queueToRetry.size} requests")

        // 按照添加顺序执行重试，每个请求间隔500ms
        queueToRetry.values.sortedBy { it.timestamp }.forEachIndexed { index, request ->
            Handler(Looper.getMainLooper()).postDelayed({
                retryRequest(request)
            }, index * 500L)
        }
    }

    /**
     * 重试单个请求
     */
    private fun retryRequest(request: RetryRequest) {
        request.retryCount++
        OkiloLog.d("NetworkErrorManager: Retry request[${request.requestId}], ${request.retryCount} retry, URL: ${request.url}")

        when (request.requestType) {
            "POST" -> {
                val params = request.params as? JSONObject
                if (params != null) {
                    // 使用原有的HttpLoader重试
                    HttpHelper.post(request.url, params, object : IHttpCallback {
                        override fun onRequestSuccess(data: JSONObject) {
                            request.originalCallback.onRequestSuccess(data)
                            onRetryRequestCompleted()
                        }

                        override fun onRequestError(error: JSONObject) {
                            OkiloLog.d("NetworkErrorManager: Retry failed - ${request.url}, error: ${error.optString("errorMsg")}")
                            // 重试失败后不再自动处理，交给业务层
                            request.originalCallback.onRequestError(error)
                            onRetryRequestCompleted()
                        }

                        override fun onRequestFinish() {
                            request.originalCallback.onRequestFinish()
                        }
                    })
                } else {
                    // 参数异常，直接标记完成
                    onRetryRequestCompleted()
                }
            }
            "UPLOAD" -> {
                val filePath = request.params as? String
                if (!filePath.isNullOrEmpty()) {
                    HttpHelper.upload(filePath, object : IHttpCallback {
                        override fun onRequestSuccess(data: JSONObject) {
                            request.originalCallback.onRequestSuccess(data)
                            onRetryRequestCompleted()
                        }

                        override fun onRequestError(error: JSONObject) {
                            OkiloLog.d("NetworkErrorManager: File upload retry failed - ${request.url}, error: ${error.optString("errorMsg")}")
                            request.originalCallback.onRequestError(error)
                            onRetryRequestCompleted()
                        }

                        override fun onRequestFinish() {
                            request.originalCallback.onRequestFinish()
                        }
                    })
                } else {
                    // 文件路径异常，直接标记完成
                    onRetryRequestCompleted()
                }
            }
            else -> {
                // 未知请求类型，直接标记完成
                onRetryRequestCompleted()
            }
        }
    }

    /**
     * 单个重试请求完成
     */
    private fun onRetryRequestCompleted() {
        completedRetryCount++
        OkiloLog.d("NetworkErrorManager: Retry progress $completedRetryCount/$pendingRetryCount")

        // 检查是否所有请求都完成
        if (completedRetryCount >= pendingRetryCount) {
            OkiloLog.d("NetworkErrorManager: retry requests have been completed")
            resetRetryCounter()
            availableActivity?.hideOkiloLoading()
        }
    }

    /**
     * 重置重试计数器
     */
    private fun resetRetryCounter() {
        pendingRetryCount = 0
        completedRetryCount = 0
    }

    /**
     * 清空重试队列
     */
    private fun clearRetryQueue() {
        synchronized(retryQueue) {
            val size = retryQueue.size
            retryQueue.clear()
        }
    }

    /**
     * 获取当前重试队列大小（用于UI显示）
     */
    fun getRetryQueueSize(): Int {
        return synchronized(retryQueue) {
            retryQueue.size
        }
    }

    /**
     * 手动添加请求到重试队列（供外部调用）
     */
    fun addRequestForRetry(request: RetryRequest) {
        addToRetryQueue(request)
    }

    /**
     * 手动触发重试（供外部调用）
     */
    fun triggerRetry() {
        executeRetryQueue()
    }

    /**
     * 重置状态
     */
    fun resetState() {
        isShowingDialog = false
        errorDialog?.dismiss()
        errorDialog = null
        clearRetryQueue()
    }
}